package com.swak.consistency.core.handle;

import com.swak.consistency.core.context.ConsistencyContext;
import com.swak.consistency.core.execption.ConsistencyException;
import com.swak.exception.BusinessException;

/**
 * 两阶段： 一致性事件处理器
 * 
 * @author DELL
 */
public interface ConsistencyHandler<T extends ConsistencyContext> {

	/**
	 * 第一阶段： 准备阶段
	 * 
	 * @param context -- 具体的事件上下文
	 * @return
	 */
	Object prepare(T context);

	/**
	 * 第一二阶段： 数据传输
	 * 
	 * @param context -- 具体的事件上下文
	 * @return
	 */
	Object transmit(T context);

	/**
	 * 第二阶段：完成阶段
	 * 
	 * @param context -- 具体的事件上下文
	 * @return
	 */
	Object complete(T context);

	/**
	 * 事务补偿
	 * 
	 * @param context
	 */
	void retry(T context);

	/**
	 * 检查是否支持
	 * 
	 * @param context
	 * @return
	 */
	default boolean support(T context) {
		return true;
	}

	/**
	 * 抛出一致性异常: ConsistencyException or BusinessException
	 * 
	 * @param error
	 */
	default Object throwConsistencyException(Throwable error) {
		if (error != null && error instanceof BusinessException) {
			throw (BusinessException) error;
		}
		if (error.getCause() != null && error.getCause() instanceof BusinessException) {
			throw (BusinessException) error.getCause();
		}
		if (error != null && error instanceof ConsistencyException) {
			throw (ConsistencyException) error;
		}
		if (error.getCause() != null && error.getCause() instanceof ConsistencyException) {
			throw (ConsistencyException) error.getCause();
		}
		throw new ConsistencyException(error);
	}
}
